package com.lg.my.netty.splitpacket;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

/**
 * 自定义的解码器 用于定义粘包拆包问题
 *
 * @author by Mr. Li 2021/4/22 7:12
 */
public class MyMessageDecode extends ByteToMessageDecoder {

    int length = 0;

    /**
     * 这里定义的逻辑是，将发送的消息用一个实体类来固定好，其中包含数据的长度一个int 类型 占4个字节
     * 一个中文 占3个ASK码 占 12个字节
     * 用这种方式，来固定好接受和发送数据的完整度，从而解决粘包拆包问题
     *
     * @param ctx channel的上下文对象
     * @param in  byteBuf 输入
     * @param out 输入的对象集合
     * @throws Exception
     */
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        System.out.println("自定义解码器 message decoder 被调用...");

        // 判断前面接受到的字节长度是否有4个
        System.out.println("当前的 byteBuf情况 ： " + in);

        if (in.readableBytes() >= 4) {
            if (length == 0) {
                length = in.readInt();
            }
            if (length > in.readableBytes()) {
                System.out.println("当前数据还未加载完毕，继续等待...");
                return;
            }
            // 组装数据
            final byte[] content = new byte[length];
            if (in.readableBytes() >= length) {
                System.out.println("存在充足的数据，准备读取数据...");
                in.readBytes(content);
                // 封装数据
                final MessageProtocol messageProtocol = new MessageProtocol();
                messageProtocol.setLen(length);
                messageProtocol.setContent(content);

                // 写出
                out.add(messageProtocol);
            }
            // 重置 读取的长度！
            length = 0;
        }
    }
}
